/*
 * Copyright (c) 2019 Actions Semiconductor Co., Ltd
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief audio_input app main.
 */

#include "audio_input.h"
#include "tts_manager.h"
#ifdef CONFIG_ESD_MANAGER
#include "esd_manager.h"
#endif

#ifdef CONFIG_PROPERTY
#include "property_manager.h"
#endif
#include <audio_hal.h>

static struct audio_input_app_t *p_audio_input = NULL;

static u8_t linein_init_state = AUDIO_INPUT_STATUS_PLAYING;
static u8_t spdif_in_init_state = AUDIO_INPUT_STATUS_PLAYING;
static u8_t mic_in_init_state = AUDIO_INPUT_STATUS_PLAYING;
static u8_t i2srx_in_init_state = AUDIO_INPUT_STATUS_PLAYING;

static u8_t temp_sample_rate = 0;

u8_t wait_tts_finish=0;
u8_t wait_tts_cnt=0;

#ifdef LINEIN_ADDA_MODE
#define AUX_SAMPLE_RATE  48
#define AUDIO_AUX_DAC_FILL_MS  8
// adc buffer大小决定了输出延时，0x1000,延时25 ms,0x800延时12.5ms.0x400延时 7ms左右。
#define AUDIO_AUX_ADC_BUFFER_LEN  0x200//AUX_SAMPLE_RATE*2*8

//static short *aux_dac_out_buffer;
void *aux_dac_out_handle;
void *aux_adc_in_handle;

short *aux_adc_in_buffer;//, *aux_adc_in_data, *aux_adc_in_data_left, *aux_adc_in_data_right;
bool aux_stereo_flag = false;
int volume_bakup=0;
u8_t audio_aux_exit=0;
u8_t key_tone_play_flag=0;
u8_t start_step=0;
u8_t remote_master_status=1;
u8_t remote_status_check_cnt=0;
u8_t remote_usb_mute=0;
void aux_send_msg_to_ap(u8_t msg_cmd,u8_t msg_data)
{
	struct app_msg  msg = {0};
	msg.type = msg_cmd;
	msg.content[0]=msg_data;
	send_async_msg("main", &msg);
}

#if 1
static int _audio_aux_dac_callback(void *cb_data, u32_t reason)
{
	//hal_aout_channel_write_data(aux_dac_out_handle, (u8_t *)aux_dac_out_buffer, sizeof(aux_1khz_1ch)*2*AUDIO_AUX_DAC_FILL_MS);
	return 0;
}
#endif
void audio_aux_set_tone_play(void)
{
	if(key_tone_play_flag)
	{
		return ;
	}
	if(systen_get_cascade_status())
	{
		return;
	}
	key_tone_play_flag=1;
	audio_aux_tts_adc_dac_ctl(0);
	sys_event_notify(SYS_EVENT_KEYTONE_MP3);
	//sys_event_notify(SYS_EVENT_MAX_VOLUME);
}
void audio_aux_set_lowpowr_play(void)
{
	SYS_LOG_INF("22222222\n");
	if(key_tone_play_flag)
	{
		return ;
	}
	SYS_LOG_INF("111111\n");
	key_tone_play_flag=1;
	audio_aux_tts_adc_dac_ctl(0);
	sys_event_notify(SYS_EVENT_BATTERY_TOO_LOW);
}

int audio_aux_set_volume(int volume,u8_t display)
{
	u32_t pa_volume = 0;
	int old_volume = system_volume_get(AUDIO_STREAM_LINEIN);
	SYS_LOG_INF(" key_tone_play_flag %d\n", key_tone_play_flag);
	if(key_tone_play_flag)
	{
		return 0;
	}
	if(old_volume==0&&volume<=0)
	{
		hal_aout_channel_mute_ctl(aux_dac_out_handle, 1);
		return 0;
	}
	if(old_volume>=audio_policy_get_volume_level()&&volume>=audio_policy_get_volume_level())
	{
		return 0;
	}
	if (display&&thread_timer_is_running(&p_audio_input->monitor_timer))
	{
		thread_timer_stop(&p_audio_input->monitor_timer);
	}	
	if (volume >=10) 
	{
		volume = 10;
	}
	else if (volume <= 0) 
	{
		volume = 0;
	}
	SYS_LOG_INF(" volume %d\n", volume);
	if (volume) {
		hal_aout_channel_mute_ctl(aux_dac_out_handle, 0);
		pa_volume = audio_policy_get_pa_volume(AUDIO_STREAM_LINEIN, volume);
		hal_aout_channel_set_pa_vol_level(aux_dac_out_handle, pa_volume);
	} else {
		hal_aout_channel_mute_ctl(aux_dac_out_handle, 1);
	}
	audio_system_set_linein_volume(volume);
	if(!display)
	{
		return 1;
	}	
	key_tone_play_flag=1;
	audio_aux_tts_adc_dac_ctl(0);
	sys_event_notify(SYS_EVENT_KEYTONE_MP3);
	//sys_event_notify(SYS_EVENT_MAX_VOLUME);
	return 1;
}
int audio_aux_volume_down(int decrement,u8_t display)
{
	audio_aux_set_volume(system_volume_get(AUDIO_STREAM_LINEIN) - decrement,display);
	if(system_volume_get(AUDIO_STREAM_LINEIN)==0)
	{
		set_key_lights(KEY_LIGHT_VOLSUB,RGB_RED);
	}
	return 1;
}

int audio_aux_volume_up(int increment,u8_t display)
{
	
	audio_aux_set_volume(system_volume_get(AUDIO_STREAM_LINEIN) + increment,display);
	if(system_volume_get(AUDIO_STREAM_LINEIN)!=0)
	{
		struct uart_msg_info remote_info;
		sys_get_remote_info(&remote_info);
		if(remote_info.ap_mode==0&&remote_info.usb_mute)
		{
			set_key_lights(KEY_LIGHT_VOLSUB,RGB_RED);
		}
		else
		{
			set_key_lights(KEY_LIGHT_VOLSUB,RGB_WHITE);
		}
	}
	return 1;
}

s32_t audio_aux_dac_start(s32_t db)
{
	audio_out_init_param_t init_param;
	int ret = 0;

	SYS_LOG_INF("audio dac start...\n");
	memset(&init_param, 0x0, sizeof(audio_out_init_param_t));
	init_param.out_to_pa = 1;
	init_param.sample_rate = AUX_SAMPLE_RATE;
	init_param.channel_type = AUDIO_CHANNEL_DAC;
	init_param.channel_mode = MONO_MODE;//STEREO_MODE;
	init_param.data_width = 16;
	init_param.left_volume = db*1000;
	init_param.right_volume = db*1000;

	init_param.callback =_audio_aux_dac_callback;

	aux_dac_out_handle = hal_aout_channel_open(&init_param);
	
	//ret = hal_aout_channel_write_data(aux_dac_out_handle, (u8_t *)aux_dac_out_buffer, sizeof(aux_1khz_1ch)*2*AUDIO_AUX_DAC_FILL_MS);

	hal_aout_channel_start(aux_dac_out_handle);

	return ret;
}

static int _audio_aux_adc_callback(void *cb_data, u32_t reason)
{
	if(reason == AIN_DMA_IRQ_TC)
	{
		hal_aout_channel_write_data(aux_dac_out_handle, (u8_t *)aux_adc_in_buffer, AUDIO_AUX_ADC_BUFFER_LEN);
	}
	return 0;
}

s32_t _audio_aux_adc_start(void)
{
	audio_in_init_param_t init_param;

	SYS_LOG_INF("audio adc start...");

	memset(&init_param, 0x0, sizeof(audio_in_init_param_t));
	init_param.need_dma = 1;
	init_param.dma_reload = 1;
	if (aux_stereo_flag == true) {
		init_param.data_mode = AUDIO_MODE_STEREO;
	} else {
		init_param.data_mode = AUDIO_MODE_DEFAULT;
	}

	init_param.sample_rate = AUX_SAMPLE_RATE;
	init_param.channel_type = AUDIO_CHANNEL_ADC;
	init_param.data_width = 16;
	init_param.left_input = AUDIO_LINE_IN0;
	init_param.right_input = AUDIO_LINE_IN0;
	init_param.adc_gain = 0;
	init_param.input_left_gain = 0;
	init_param.input_right_gain = 0;

	init_param.reload_len = AUDIO_AUX_ADC_BUFFER_LEN;
	init_param.reload_addr = (u8_t *)aux_adc_in_buffer;

	init_param.callback = _audio_aux_adc_callback;
	
	aux_adc_in_handle = hal_ain_channel_open(&init_param);
	
	hal_ain_channel_start(aux_adc_in_handle);
	
	return 0;
}


void audio_aux_tts_delay_resume(struct thread_timer *ttimer, void *expiry_fn_arg)
{
	audio_aux_set_volume(volume_bakup,0);
}
void audio_aux_volume_delay_resume(struct thread_timer *ttimer, void *expiry_fn_arg)
{	
	SYS_LOG_INF("............\n");
	audio_aux_set_volume(volume_bakup,0);	
}
void audio_aux_sync_remote_volume(u8_t sync_vol)
{
	volume_bakup=sync_vol;
	SYS_LOG_INF("sync vol:%d->key_tone_play_flag:%d\n",sync_vol,key_tone_play_flag);
	if(!key_tone_play_flag)
	{
		audio_aux_set_volume(sync_vol,0);
		if(system_volume_get(AUDIO_STREAM_LINEIN)==0)
		{
			set_key_lights(KEY_LIGHT_VOLSUB,RGB_RED);
		}
		else
		{
			set_key_lights(KEY_LIGHT_VOLSUB,RGB_WHITE);
		}
	}
}
u8_t audio_aux_get_status(void)
{
	if(start_step==2)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
void audio_aux_start_delay_resume(struct thread_timer *ttimer, void *expiry_fn_arg)
{	
	start_step++;
	SYS_LOG_INF("start_step:%d\n",start_step);
	if(start_step==1)
	{
		_audio_aux_adc_start();
		//system_sync_to_remote_start(ACK_OUT,CMD_SYNC_ALL);
	}
	else if(start_step==2)
	{
		struct uart_msg_info remote_info;
		//u8_t msg_type;
		if (thread_timer_is_running(&p_audio_input->monitor_timer))
		{
			thread_timer_stop(&p_audio_input->monitor_timer);
		}
		audio_aux_set_volume(volume_bakup,0);
		sys_get_remote_info(&remote_info);
		if(remote_info.sync_vol!=system_volume_get(AUDIO_STREAM_LINEIN))
		{
			audio_aux_sync_remote_volume(remote_info.sync_vol);
		}
		//system_sync_to_remote_start(ACK_OUT,CMD_SYNC_ALL);	
	}
	#if 0
	else
	{
		struct uart_msg_info remote_info;
		u8_t msg_type;
		
		if (thread_timer_is_running(&p_audio_input->monitor_timer))
		{
			thread_timer_stop(&p_audio_input->monitor_timer);
		}
		sys_get_remote_info(&remote_info);
		if(remote_info.mute!=system_get_mic_status())
		{		
			if(remote_info.mute)
			{
				msg_type=MSG_MUTE_EN_EVENT;
			}
			else
			{
				msg_type=MSG_MUTE_DIS_EVENT;
			}
			aux_send_msg_to_ap(msg_type,0);						
		}
		if(remote_info.sync_vol!=system_volume_get(AUDIO_STREAM_LINEIN))
		{
			audio_aux_sync_remote_volume(remote_info.sync_vol);
		}
		if(remote_info.bt_status>=2)
		{
			audio_input_set_hung_led(1);
		}
		else
		{
			audio_input_set_hung_led(0);
		}
		start_step=0;
	}
	#endif

	//audio_aux_set_volume(volume_bakup,0);
	//system_sync_to_remote_start(ACK_OUT,CMD_SYNC_ALL);
}

void audio_aux_auto_set_vol(struct thread_timer *ttimer, void *expiry_fn_arg)
{
	int cur_volume;
	cur_volume=system_volume_get(AUDIO_STREAM_LINEIN);
	SYS_LOG_INF("cur vol:%d->bak vol:%d\n",cur_volume,volume_bakup);
	if(cur_volume<volume_bakup)
	{
		audio_aux_set_volume(cur_volume+1,0);
	}
	else
	{
		thread_timer_stop(&p_audio_input->monitor_timer);
	}
}

void audio_aux_play_ctl(void)
{
	if(linein_init_state == AUDIO_INPUT_STATUS_PLAYING)
	{
		linein_init_state=AUDIO_INPUT_STATUS_PAUSED;
		hal_ain_channel_stop(aux_adc_in_handle);
		hal_ain_channel_close(aux_adc_in_handle);
		sys_wake_unlock(WAKELOCK_PLAYER);
	}
	else
	{
		linein_init_state=AUDIO_INPUT_STATUS_PLAYING;
		_audio_aux_adc_start();
		sys_wake_lock(WAKELOCK_PLAYER);
	}
}
void audio_aux_tts_adc_dac_ctl(u8_t onoff)
{
	if(!onoff)
	{
		if(linein_init_state == AUDIO_INPUT_STATUS_PLAYING)
		{
			hal_ain_channel_stop(aux_adc_in_handle);
			hal_ain_channel_close(aux_adc_in_handle);
			
		}
		hal_aout_channel_close(aux_dac_out_handle);
		volume_bakup=system_volume_get(AUDIO_STREAM_LINEIN);
	}
	else
	{
		if(linein_init_state == AUDIO_INPUT_STATUS_PLAYING)
		{
			_audio_aux_adc_start();
		}
		audio_aux_dac_start(0);	
		audio_aux_set_volume(0,0);
		//audio_aux_set_volume(volume_bakup,0);
		
	}
}
void tts_restor_aux_play_status(void)
{
	audio_aux_tts_adc_dac_ctl(1);
	thread_timer_init(&p_audio_input->monitor_timer, audio_aux_tts_delay_resume, NULL);
	thread_timer_start(&p_audio_input->monitor_timer, 250, 0);
}
void audio_sync_vol_from_remote_device(u8_t sync_vol)
{
	SYS_LOG_INF("sync vol:%d\n",sync_vol);
	if(wait_tts_finish)
	{
		volume_bakup=sync_vol;
		audio_system_set_linein_volume(volume_bakup);
	}
	else
	{
		audio_aux_sync_remote_volume(sync_vol);
	}
	
	#if 0
	audio_aux_set_volume(sync_vol,0);
	if(system_volume_get(AUDIO_STREAM_LINEIN)==0)
	{
		set_key_lights(KEY_LIGHT_VOLSUB,RGB_RED);
	}
	else
	{
		set_key_lights(KEY_LIGHT_VOLSUB,RGB_WHITE);
	}
	#endif
}


void audio_aux_connect_timer(struct thread_timer *ttimer, void *expiry_fn_arg)
{
	if(!remote_master_status)//级联连接失败后，退出从机模式
	{
		remote_status_check_cnt++;
		SYS_LOG_INF("timer out cnt:%d\n",remote_status_check_cnt);
		if(remote_status_check_cnt>2)
		{
			remote_status_check_cnt=0;
			if (thread_timer_is_running(&p_audio_input->connect_timer))
			thread_timer_stop(&p_audio_input->connect_timer);
			SYS_LOG_INF("CASCADE time out!!!\n");
			systen_set_cascade_status(0);
			aux_send_msg_to_ap(MSG_SWITCH_AP_MASTER,0);		
			return;
		}
		
	}
	else
	{
		remote_status_check_cnt=0;
	}
	if(!systen_get_cascade_status())//级联连接失败后，退出从机模式
	{
		struct app_msg  msg = {0};
		msg.type = MSG_SWITCH_AP_MASTER;
		msg.content[0]=0;
		if (thread_timer_is_running(&p_audio_input->connect_timer))
		thread_timer_stop(&p_audio_input->connect_timer);
		send_async_msg("main", &msg);
		return;
	}
	//SYS_LOG_INF("check master statse!!!\n");
	//system_sync_to_remote_start(ACK_OUT,CMD_SYNC_CASCADE_STATUS);
	remote_master_status=0;
}
void audio_set_cascade_in(void)
{
	remote_master_status=1;
	remote_status_check_cnt=0;
	//SYS_LOG_INF("reset status!!!\n");
}
void audio_adda_channel_test(void)
{
	//sys_get_remote_info(&remote_info);
	//if(wait_tts_finish==0)
	{
		struct uart_msg_info remote_info;
		u8_t msg_type;
		sys_get_remote_info(&remote_info);
		if(remote_info.mute!=system_get_mic_status())
		{		
			if(remote_info.mute)
			{
				msg_type=MSG_MUTE_EN_EVENT;
			}
			else
			{
				msg_type=MSG_MUTE_DIS_EVENT;
			}
			aux_send_msg_to_ap(msg_type,0);						
		}
		
		if(remote_info.bt_status>=2)
		{
			audio_input_set_hung_led(1);
		}
		else
		{
			audio_input_set_hung_led(0);
		}
		if(start_step!=2)
		{
			if(remote_info.sync_vol==0)
			{
				set_key_lights(KEY_LIGHT_VOLSUB,RGB_RED);
			}
			else
			{
				set_key_lights(KEY_LIGHT_VOLSUB,RGB_WHITE);
			}
		}
		audio_system_set_linein_volume(remote_info.sync_vol);
		SYS_LOG_INF("start step:%d->sync vol:%d\n",start_step,remote_info.sync_vol);
		
	}
	wait_tts_finish=0;
	audio_aux_exit=0;		
	audio_aux_dac_start(-60);
	
	volume_bakup=system_volume_get(AUDIO_STREAM_LINEIN);
	audio_aux_set_volume(0,0);
	aux_adc_in_buffer = app_mem_malloc(AUDIO_AUX_ADC_BUFFER_LEN);
	if (aux_adc_in_buffer == NULL)
	{
		SYS_LOG_INF("malloc fail 111\n");
		app_mem_free(aux_adc_in_buffer);
		return;
	}
	//_audio_aux_adc_start();
	linein_init_state = AUDIO_INPUT_STATUS_PLAYING;
	
	//k_sleep(500);
	//_audio_aux_adc_start();
	sys_wake_lock(WAKELOCK_PLAYER);
	thread_timer_init(&p_audio_input->monitor_timer, audio_aux_start_delay_resume, NULL);
	thread_timer_start(&p_audio_input->monitor_timer, 800, 600);
	
	audio_set_cascade_in();
	linein_func_switch(0);

	
	//system_sync_to_remote_start(ACK_OUT,CMD_SYNC_ALL);
}
s32_t audio_adc_stop(void)
{
	if(audio_aux_exit)
	{
		return 0;
	}
	sys_wake_unlock(WAKELOCK_PLAYER);
	if(aux_adc_in_handle)
	{
		hal_ain_channel_stop(aux_adc_in_handle);
		hal_ain_channel_close(aux_adc_in_handle);
	}
	
	if(aux_dac_out_handle)
	{
		hal_aout_channel_close(aux_dac_out_handle);
	}
	
	if(aux_adc_in_buffer)
	{
		app_mem_free(aux_adc_in_buffer);
	}
	
	audio_aux_exit=1;
	return 0;
}


#endif

int audio_input_spdifrx_event_cb(void *cb_data, u32_t cmd, void *param)
{
	if (!p_audio_input)
		return 0;

	if (cmd == SPDIFRX_SRD_FS_CHANGE) {
		temp_sample_rate = *(u8_t *)param;
		os_delayed_work_submit(&p_audio_input->spdifrx_cb_work, 2);
		p_audio_input->spdifrx_srd_event = SPDIFRE_SAMPLE_RATE_CHANGE;
#ifndef CONFIG_SOUNDBAR_AUDIOIN_STAY
	} else if (cmd == SPDIFRX_SRD_TIMEOUT) {
		p_audio_input->spdifrx_srd_event = SPDIFRE_TIME_OUT;
		os_delayed_work_submit(&p_audio_input->spdifrx_cb_work, 2);
#endif
	}
	SYS_LOG_INF("cmd=%d, param=%d\n", cmd,  *(u8_t *)param);
	return 0;
}

int audio_input_i2srx_event_cb(void *cb_data, u32_t cmd, void *param)
{
	if (!p_audio_input)
		return 0;
	SYS_LOG_INF("cmd=%d, param=%d\n", cmd,  *(u8_t *)param);
	if (cmd == I2SRX_SRD_FS_CHANGE) {
		temp_sample_rate = *(u8_t *)param;
		os_delayed_work_submit(&p_audio_input->i2srx_cb_work, 2);
		p_audio_input->i2srx_srd_event = I2SRX_SAMPLE_RATE_CHANGE;
#ifndef CONFIG_SOUNDBAR_AUDIOIN_STAY
	} else if (cmd == SPDIFRX_SRD_TIMEOUT) {
		p_audio_input->i2srx_srd_event = I2SRX_TIME_OUT;
		os_delayed_work_submit(&p_audio_input->i2srx_cb_work, 2);
#endif
	}
	return 0;
}


static void _spdifrx_isr_event_callback_work(struct k_work *work)
{
	struct app_msg msg = { 0 };

	if (!p_audio_input)
		return;

	if (p_audio_input->ain_handle) {
		hal_ain_channel_close(p_audio_input->ain_handle);
		p_audio_input->ain_handle = NULL;
	}

	if (p_audio_input->spdifrx_srd_event == SPDIFRE_SAMPLE_RATE_CHANGE) {
		if (temp_sample_rate != p_audio_input->spdif_sample_rate || !p_audio_input->player) {
			p_audio_input->spdif_sample_rate = temp_sample_rate;
			msg.type = MSG_INPUT_EVENT;
			msg.cmd = MSG_AUDIO_INPUT_SAMPLE_RATE_CHANGE;
			send_async_msg(app_manager_get_current_app(), &msg);
		}
#ifndef CONFIG_SOUNDBAR_AUDIOIN_STAY
	} else if (p_audio_input->spdifrx_srd_event == SPDIFRE_TIME_OUT) {
		msg.type = MSG_INPUT_EVENT;
		msg.cmd = MSG_SWITCH_APP;
		msg.ptr = APP_ID_DEFAULT;
		send_async_msg(APP_ID_MAIN, &msg);
#endif
	}
	SYS_LOG_INF("\n");
}

static void _i2srx_isr_event_callback_work(struct k_work *work)
{
	struct app_msg msg = { 0 };

	if (!p_audio_input)
		return;
	if (p_audio_input->ain_handle) {
		hal_ain_channel_close(p_audio_input->ain_handle);
		p_audio_input->ain_handle = NULL;
	}

	if (p_audio_input->i2srx_srd_event == I2SRX_SAMPLE_RATE_CHANGE) {
		if (temp_sample_rate != p_audio_input->i2srx_sample_rate || !p_audio_input->player) {
			p_audio_input->i2srx_sample_rate = temp_sample_rate;
			msg.type = MSG_INPUT_EVENT;
			msg.cmd = MSG_AUDIO_INPUT_SAMPLE_RATE_CHANGE;
			send_async_msg(app_manager_get_current_app(), &msg);
		}
#ifndef CONFIG_SOUNDBAR_AUDIOIN_STAY
	} else if (p_audio_input->i2srx_srd_event == I2SRX_TIME_OUT) {
		msg.type = MSG_INPUT_EVENT;
		msg.cmd = MSG_SWITCH_APP;
		msg.ptr = APP_ID_DEFAULT;
		send_async_msg(APP_ID_MAIN, &msg);
#endif
	}
	SYS_LOG_INF("\n");
}



void audio_input_delay_resume(struct thread_timer *ttimer, void *expiry_fn_arg)
{
	if (memcmp(app_manager_get_current_app(), APP_ID_SPDIF_IN, strlen(APP_ID_SPDIF_IN)) == 0) {
#ifdef CONFIG_DVFS_DYNAMIC_LEVEL
		dvfs_set_level(DVFS_LEVEL_HIGH_PERFORMANCE, "spdif");
#endif
		audio_in_init_param_t init_param = { 0 };

		init_param.channel_type = AUDIO_CHANNEL_SPDIFRX;
		p_audio_input->ain_handle = hal_ain_channel_open(&init_param);
	} else {
		audio_input_start_play();
	}
	p_audio_input->need_resume_play = 0;
}
#ifndef  LINEIN_ADDA_MODE

static void _audio_input_restore_play_state(u8_t init_play_state)
{
#ifdef CONFIG_ESD_MANAGER
	if (esd_manager_check_esd()) {
		esd_manager_restore_scene(TAG_PLAY_STATE, &init_play_state, 1);
	}
#endif

	if (init_play_state == AUDIO_INPUT_STATUS_PLAYING) {
		p_audio_input->playing = 1;
		if (thread_timer_is_running(&p_audio_input->monitor_timer)) {
			thread_timer_stop(&p_audio_input->monitor_timer);
		}
		thread_timer_init(&p_audio_input->monitor_timer, audio_input_delay_resume, NULL);
		thread_timer_start(&p_audio_input->monitor_timer, 800, 0);
		audio_input_show_play_status(true);
	} else {
		p_audio_input->playing = 0;
		audio_input_show_play_status(false);
	}
	audio_input_store_play_state();

	SYS_LOG_INF("%d\n", init_play_state);
}
#endif
void audio_input_store_play_state(void)
{
	if (p_audio_input->playing) {
		if (memcmp(app_manager_get_current_app(), APP_ID_LINEIN, strlen(APP_ID_LINEIN)) == 0)
			linein_init_state = AUDIO_INPUT_STATUS_PLAYING;
		else if (memcmp(app_manager_get_current_app(), APP_ID_MIC_IN, strlen(APP_ID_MIC_IN)) == 0)
			mic_in_init_state = AUDIO_INPUT_STATUS_PLAYING;
		else if (memcmp(app_manager_get_current_app(), APP_ID_SPDIF_IN, strlen(APP_ID_SPDIF_IN)) == 0)
			spdif_in_init_state = AUDIO_INPUT_STATUS_PLAYING;
		else if (memcmp(app_manager_get_current_app(), APP_ID_I2SRX_IN, strlen(APP_ID_I2SRX_IN)) == 0)
			i2srx_in_init_state = AUDIO_INPUT_STATUS_PLAYING;
	} else {
	linein_init_state = AUDIO_INPUT_STATUS_PAUSED;
		if (memcmp(app_manager_get_current_app(), APP_ID_LINEIN, strlen(APP_ID_LINEIN)) == 0)
			linein_init_state = AUDIO_INPUT_STATUS_PAUSED;
		else if (memcmp(app_manager_get_current_app(), APP_ID_MIC_IN, strlen(APP_ID_MIC_IN)) == 0)
			mic_in_init_state = AUDIO_INPUT_STATUS_PAUSED;
		else if (memcmp(app_manager_get_current_app(), APP_ID_SPDIF_IN, strlen(APP_ID_SPDIF_IN)) == 0)
			spdif_in_init_state = AUDIO_INPUT_STATUS_PAUSED;
		else if (memcmp(app_manager_get_current_app(), APP_ID_I2SRX_IN, strlen(APP_ID_I2SRX_IN)) == 0)
			i2srx_in_init_state = AUDIO_INPUT_STATUS_PAUSED;
	}
}

#ifdef CONFIG_AUDIO_INPUT_ENERGY_DETECT_DEMO
void audio_input_energy_detect(struct thread_timer *ttimer, void *expiry_fn_arg)
{
	struct audio_input_app_t *audio_input = audio_input_get_app();
	if (audio_input->player && audio_input->playing) {
		energy_detect_info_t energy_detect_info;
		media_player_get_energy_detect(audio_input->player, &energy_detect_info);
		SYS_LOG_INF("energy:%d,%d,%d\n", energy_detect_info.energy_stat_average, \
			energy_detect_info.energy_stat_duration_ms, \
			energy_detect_info.energy_lowpower_duration_ms);
	}
}
#endif

static int _audio_input_init(void)
{
	if (p_audio_input)
		return 0;

	p_audio_input = app_mem_malloc(sizeof(struct audio_input_app_t));
	if (!p_audio_input) {
		SYS_LOG_ERR("malloc failed!\n");
		return -ENOMEM;
	}
#ifdef CONFIG_TWS
#ifndef CONFIG_TWS_BACKGROUND_BT
	bt_manager_halt_phone();
#else
	if (system_check_low_latencey_mode()) {
		bt_manager_halt_phone();
	}
#endif
#endif

	memset(p_audio_input, 0, sizeof(struct audio_input_app_t));

	audio_input_view_init();
	if (memcmp(app_manager_get_current_app(), APP_ID_SPDIF_IN, strlen(APP_ID_SPDIF_IN)) == 0) {
		hal_ain_set_contrl_callback(AUDIO_CHANNEL_SPDIFRX, audio_input_spdifrx_event_cb);
		os_delayed_work_init(&p_audio_input->spdifrx_cb_work, _spdifrx_isr_event_callback_work);
	}

	if (memcmp(app_manager_get_current_app(), APP_ID_I2SRX_IN, strlen(APP_ID_I2SRX_IN)) == 0) {
		hal_ain_set_contrl_callback(AUDIO_CHANNEL_I2SRX, audio_input_i2srx_event_cb);
		os_delayed_work_init(&p_audio_input->i2srx_cb_work, _i2srx_isr_event_callback_work);
	}

#ifdef CONFIG_AUDIO_INPUT_ENERGY_DETECT_DEMO
	thread_timer_init(&p_audio_input->energy_detect_timer, audio_input_energy_detect, NULL);
	thread_timer_start(&p_audio_input->energy_detect_timer, 1000, 1000);
#endif

	SYS_LOG_INF("ok\n");
	return 0;
}
void _audio_input_exit(void)
{
	if (!p_audio_input)
		goto exit;

#ifdef CONFIG_AUDIO_INPUT_ENERGY_DETECT_DEMO
	if (thread_timer_is_running(&p_audio_input->energy_detect_timer))
		thread_timer_stop(&p_audio_input->energy_detect_timer);
#endif
	if (thread_timer_is_running(&p_audio_input->monitor_timer))
		thread_timer_stop(&p_audio_input->monitor_timer);
	if (thread_timer_is_running(&p_audio_input->connect_timer))
		thread_timer_stop(&p_audio_input->connect_timer);
	if (thread_timer_is_running(&p_audio_input->bat_check_timer))
		{
			thread_timer_stop(&p_audio_input->bat_check_timer);
		}
	audio_input_stop_play();
#ifdef LINEIN_ADDA_MODE
	audio_adc_stop();
#endif
	if(start_step!=2)
	{		
		audio_system_set_linein_volume(volume_bakup);
	}
	start_step=0;
	if (p_audio_input->ain_handle) {
		hal_ain_channel_close(p_audio_input->ain_handle);
		p_audio_input->ain_handle = NULL;
		os_delayed_work_cancel(&p_audio_input->spdifrx_cb_work);
	}

	audio_input_view_deinit();

	app_mem_free(p_audio_input);

	p_audio_input = NULL;

#ifdef CONFIG_PROPERTY
	property_flush_req(NULL);
#endif
	linein_func_switch(1);
	#if 0
	if (hotplug_manager_get_state(HOTPLUG_LINEIN) == HOTPLUG_IN)
	{
		linein_func_switch(1);
	}
	else
	{
		linein_func_switch(0);
	}
	#endif
exit:
	app_manager_thread_exit(app_manager_get_current_app());

	SYS_LOG_INF("ok\n");
}
void aux_send_msg_to_cur_ap(void)
{
	struct app_msg  msg = {0};
	msg.type = MSG_INPUT_EVENT;
	msg.cmd = MSG_AUDIO_TTS_END;
	send_async_msg(APP_ID_LINEIN, &msg);
}

void audio_aux_check_tts_timer(struct thread_timer *ttimer, void *expiry_fn_arg)
{
	
	if(!tts_manager_get_status())
	{
		wait_tts_cnt++;
		SYS_LOG_INF("wait_tts_cnt:%d\n",wait_tts_cnt);
		if(wait_tts_cnt>3)
		{			
			wait_tts_finish=0;
			wait_tts_cnt=0;
			system_sync_to_remote_start(ACK_OUT,CMD_SYNC_ALL);
			if (thread_timer_is_running(&p_audio_input->bat_check_timer))
			{
				thread_timer_stop(&p_audio_input->bat_check_timer);
			}
			aux_send_msg_to_cur_ap();
		}
	}
	else
	{
		wait_tts_cnt=0;
	}
	wait_tts_finish++;
	if(wait_tts_finish>30)
	{
		wait_tts_finish=0;
		if (thread_timer_is_running(&p_audio_input->bat_check_timer))
		{
			thread_timer_stop(&p_audio_input->bat_check_timer);
		}
		aux_send_msg_to_cur_ap();
	}
}

static void _audio_input_main_prc(u8_t init_play_state)
{
	struct app_msg msg = { 0 };

	bool terminated = false;

	if (_audio_input_init()) {
		SYS_LOG_ERR("init failed");
		_audio_input_exit();
		return;
	}
	#ifdef  LINEIN_ADDA_MODE	
	system_sync_to_remote_start(ACK_OUT,CMD_SYNC_ALL);
	sys_event_notify(SYS_EVENT_ENTER_LINEIN);
	wait_tts_finish=1;
	wait_tts_cnt=0;
	start_step=0;
	remote_usb_mute=0;
	thread_timer_init(&p_audio_input->bat_check_timer, audio_aux_check_tts_timer, NULL);
	thread_timer_start(&p_audio_input->bat_check_timer, 1000, 100);
	thread_timer_init(&p_audio_input->connect_timer, audio_aux_connect_timer, NULL);
	thread_timer_start(&p_audio_input->connect_timer, 100, 500);
	#if 0
	if(!tts_manager_get_status())
	{
		//audio_adda_channel_test();
		wait_tts_finish=1;
		
	}
	else
	{
		wait_tts_finish=2;
		
	}
	#endif
	#else
	_audio_input_restore_play_state(init_play_state);
	#endif

	while (!terminated) {
		if (receive_msg(&msg, thread_timer_next_timeout())) {
			SYS_LOG_INF("type %d, value %d\n", msg.type, msg.value);
			switch (msg.type) {
			case MSG_INPUT_EVENT:
				audio_input_input_event_proc(&msg);
				break;

			case MSG_TTS_EVENT:
				audio_input_tts_event_proc(&msg);
				break;
			case MSG_BT_EVENT:
				audio_input_bt_event_proc(&msg);
				break;
			case MSG_SYNC_VOL_EVENT:
				audio_sync_vol_from_remote_device(msg.content[0]);
				break;
			case MSG_SYNC_KEY_MSG_EVENT:
				audio_input_sync_event_proc(&msg);
				break;
			case MSG_EXIT_APP:
				_audio_input_exit();
				terminated = true;
				break;
			default:
				break;
			}
			if (msg.callback)
				msg.callback(&msg, 0, NULL);
		}
		if (!terminated)
			thread_timer_handle_expired();
	}
}
struct audio_input_app_t *audio_input_get_app(void)
{
	return p_audio_input;
}

static void audio_input_linein_main_loop(void *parama1, void *parama2, void *parama3)
{
	u8_t init_play_state = *(u8_t *) parama1;

	SYS_LOG_INF("Enter\n");

	//sys_event_notify(SYS_EVENT_ENTER_LINEIN);

	bt_manager_set_stream_type(AUDIO_STREAM_LINEIN);

	_audio_input_main_prc(init_play_state);

	SYS_LOG_INF("Exit\n");
}


APP_DEFINE(linein, share_stack_area, sizeof(share_stack_area),
	   CONFIG_APP_PRIORITY, FOREGROUND_APP, &linein_init_state, NULL, NULL,
	   audio_input_linein_main_loop, NULL);

static void audio_input_spdif_in_main_loop(void *parama1, void *parama2, void *parama3)
{
	u8_t init_play_state = *(u8_t *) parama1;

	SYS_LOG_INF("Enter\n");
	sys_event_notify(SYS_EVENT_ENTER_SPDIF_IN);

	bt_manager_set_stream_type(AUDIO_STREAM_SPDIF_IN);

	_audio_input_main_prc(init_play_state);
	SYS_LOG_INF("Exit\n");
}
APP_DEFINE(spdif_in, share_stack_area, sizeof(share_stack_area),
	   CONFIG_APP_PRIORITY, FOREGROUND_APP, &spdif_in_init_state, NULL, NULL,
	   audio_input_spdif_in_main_loop, NULL);

static void audio_input_i2srx_in_main_loop(void *parama1, void *parama2, void *parama3)
{
   u8_t init_play_state = *(u8_t *) parama1;

   SYS_LOG_INF("Enter\n");
   sys_event_notify(SYS_EVENT_ENTER_I2SRX_IN);

   bt_manager_set_stream_type(AUDIO_STREAM_I2SRX_IN);

   _audio_input_main_prc(init_play_state);
   SYS_LOG_INF("Exit\n");
}
APP_DEFINE(i2srx_in, share_stack_area, sizeof(share_stack_area),
	  CONFIG_APP_PRIORITY, FOREGROUND_APP, &spdif_in_init_state, NULL, NULL,
	  audio_input_i2srx_in_main_loop, NULL);

static void audio_input_mic_in_main_loop(void *parama1, void *parama2, void *parama3)
{
	u8_t init_play_state = *(u8_t *) parama1;

	SYS_LOG_INF("Enter\n");
	sys_event_notify(SYS_EVENT_ENTER_MIC_IN);

	bt_manager_set_stream_type(AUDIO_STREAM_MIC_IN);

	_audio_input_main_prc(init_play_state);
	SYS_LOG_INF("Exit\n");
}
APP_DEFINE(mic_in, share_stack_area, sizeof(share_stack_area),
	CONFIG_APP_PRIORITY, FOREGROUND_APP, &mic_in_init_state, NULL, NULL,
	audio_input_mic_in_main_loop, NULL);

